from flask.views import MethodView
from flask import jsonify
import re
from flask import request
from base.public import shorten_url_sha256 #将长url转成16位长度的字符串
import time
from base.redis_pool import pool_redis #redis连接池
from apps.short_url_app import models as short_models
from base.public import URL_MAX_ID_URL #short_url表中，最大id存到redis数据库中的key
from base.public import is_http_url #判断字符串是否是http网址
from base.public import REDIRECT_HOST #短网址的前缀地址
from ext import db
from sqlalchemy import func
from flask import render_template

class HomeView(MethodView):
    def get(self):
        return render_template('home/home.html')


class ShortUrlMaxIdView(MethodView):
    def get(self):
        '''
        功能：获取当前系统中，存的短网址的数量，返回最近一次新增的短网址的id值
        :return:
        '''
        max_id = pool_redis.get(URL_MAX_ID_URL)
        if isinstance(max_id,bytes):
            max_id = int(max_id.decode())
        if not max_id:
            short_obj = short_models.ShortUrlModel.query.order_by(
                short_models.ShortUrlModel.id.desc()
            ).first()
            max_id = short_obj.id
        return jsonify({'code':200,'max_id':max_id})

class MakeShortUrlView(MethodView):
    def get(self):
        '''
        功能： 获取短地址对应的长地址，只需携带短地址的后缀
        例子：url=http://127.0.0.1:5000/k9kPiCCHt3yz24g9
        提取出：k9kPiCCHt3yz24g9，查询到长地址，返回原长地址
        :return:
        '''
        short_url = request.args.get('url')
        if not short_url:
            return jsonify({'code':400,'error':'没有携带短地址'})
        if REDIRECT_HOST in short_url:
            pattern = r'/([^/]+)$'
            match = re.search(pattern,short_url)
            short_url = match.group(1)
        else:
            return jsonify({'code':400,'error':'携带的http地址有问题'})

        short_obj = short_models.ShortUrlModel.query.filter_by(short_url=short_url).first()
        if short_obj:
            url = f'{short_obj.long_url}'
            return jsonify({'code':200,'url':url})
        else:
            return jsonify({'code':400,'error':'查询不到数据'})

    def post(self):
        '''
        功能：将长http地址转成成一个16位长度的字符串，存到数据库中
        返回：跳转的域名和端口+ 16字符串， 短网址字符串。[注意：在返回短网址时，会先查询到长网址，再进行跳转]
        :return:
        '''
        # long_url = request.args.get('url')
        long_url = request.form.get('url')
        if not long_url:
            return jsonify({'code':400,'error':'请携带上要转换的url'})

        if is_http_url(long_url) == False:
            return jsonify({'code':400,'error':'请输入合法的http网址'})

        the_time = str(time.time())
        max_id = pool_redis.get(URL_MAX_ID_URL)
        if not max_id:
            # 每次项目启动时，就将短地址的最大存到redis数据库中
            max_id = db.session.query(func.max(short_models.ShortUrlModel.id)).scalar()
            if not max_id:
                max_id = 0
            pool_redis.set(URL_MAX_ID_URL, max_id, ex=-1)
        if isinstance(max_id,bytes):
            max_id = int(max_id.decode())
        print(max_id,'max_id')
        #取到的max_id,是已经记录到数据库中的，所有在生成新的短url时，需要给max_id+1, 是该记录创建时的id值了
        try:
            short_url = shorten_url_sha256(long_url=long_url,the_time=the_time,url_id=max_id+1)
            #将短地址记录起来
            short_obj = short_models.ShortUrlModel(
                short_url=short_url,
                long_url=long_url,
                the_time=the_time
            )
            db.session.add(short_obj)
            db.session.commit()
            db.session.close()
            pool_redis.incr(URL_MAX_ID_URL)  # 最大id值自增
        except Exception as _:
            print(_)
            return jsonify({'code':400,'error':'操作失败，请重试'})
        url = f'{REDIRECT_HOST}{short_url}'
        return jsonify({'code':200,'url':url})
